package com.softer.chengxin.excel.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.softer.chengxin.common.domin.*;
import com.softer.chengxin.common.enums.NumberEnum;
import com.softer.chengxin.common.enums.ResultEnum;
import com.softer.chengxin.common.util.MapUtil;
import com.softer.chengxin.corp.dao.CorpDao;
import com.softer.chengxin.excel.dao.ExcelDao;
import com.softer.chengxin.excel.domin.ExcelExportRecordVO;
import com.softer.chengxin.excel.domin.ExportExcel;
import com.softer.chengxin.excel.domin.MenuDTO;
import com.softer.chengxin.excel.service.ExcelService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Wang Xinrui
 * @date 2019/1/10
 */
@Service
public class ExcelServiceImpl implements ExcelService {

    @Autowired
    private ExcelDao excelDao;
    @Autowired
    private CorpDao corpDao;

    /**
     * 获取excel列表
     *
     * @param excelName 报表名
     * @param loginName 登录名
     * @param page      页码
     * @param excelType 报表类型（0自定义报表，1统计报表）
     * @return 结果集
     */
    @Override
    public ManagerPageResult getExcelList(String excelName, String loginName, Page page, String excelType) {
        ManagerPageResult mpr = new ManagerPageResult();
        JsonResult jr = new JsonResult();
        int count = excelDao.countExcel(loginName, excelName, excelType);
        if (count <= NumberEnum.ZERO.getNum()) {
            commonResult(mpr, jr);
            return mpr;
        }
        List<ExcelExportRecordVO> list = excelDao.listExcels(loginName, page, excelName, excelType);
        jr.setDs(list);
        mpr.setCount(count);
        mpr.setJson(jr);
        return mpr;
    }

    /**
     * excel记录详细
     *
     * @param id id
     * @return 结果
     */
    @Override
    public ExcelExportRecordVO excelDetail(Integer id) {
        ExcelExportRecordVO recordDetail = excelDao.excelDetail(id);
        String excelObj = recordDetail.getExcelObj();
        recordDetail.setExcelObjJSON(JSONArray.parseArray(excelObj));
        return recordDetail;
    }

    /**
     * 删除excel记录
     *
     * @param id id
     * @return 结果集
     */
    @Override
    public CommonResult deleteExcel(Integer id) {
        int ret = excelDao.deleteExcel(id);
        if (ret == NumberEnum.ONE.getNum()) {
            return new CommonResult(ResultEnum.SUCCESS.getCode(), "删除成功！");
        }
        return new CommonResult(ResultEnum.FAIL.getCode(), "删除失败！");
    }

    /**
     * 获取导出excel页面的字段
     *
     * @param parentId 父id
     * @return 结果
     */
    @Override
    public List<MenuDTO> listMenus(Integer parentId) {
        return excelDao.listMenus(parentId);
    }

    /**
     * 导出报表数据
     *
     * @param exportExcel 报表实体
     *                    <p>
     *                    fields          需要导出的字段字符串
     *                    type            报表类型
     *                    district        所在地
     *                    qyName          企业名
     *                    projectName     项目名
     *                    insurance       是否缴纳五险一金
     *                    certificate     是否有中级职业资格证书
     *                    duties          职务，人员类型
     *                    year            年度
     *                    dj              等级
     *                    department      培训部门
     *                    subject         培训科目
     *                    excelName       excel名
     *                    excelRecordId   登录名excel记录id（如果不为空说明是修改记录，如果为空新怎）
     *                    isCX            是否是查询接口
     *                    infoType        消息类型(1优良信息，2负面信息)
     *                    registerAddress 注册地
     * @param page        页码
     * @param loginName   登录名
     * @return 结果集
     */
    @Override
    public ManagerPageResult exportExcel(ExportExcel exportExcel, Page page, String loginName) {
        String fields = exportExcel.getFields();
        Integer type = exportExcel.getType();
        Integer isCX = exportExcel.getIsCX();
        String excelName = exportExcel.getExcelName();
        Integer excelRecordId = exportExcel.getExcelRecordId();
        Integer district = exportExcel.getDistrict();
        String registerAddress = exportExcel.getRegisterAddress();
        String qyName = exportExcel.getQyName();
        String insurance = exportExcel.getInsurance();
        String certificate = exportExcel.getCertificate();
        String duties = exportExcel.getDuties();
        String department = exportExcel.getDepartment();
        String dj = exportExcel.getDj();
        String year = exportExcel.getYear();
        String projectName = exportExcel.getProName();
        Integer infoType = exportExcel.getInfoType();
        String subject = exportExcel.getSubject();
        String street = exportExcel.getStreet();
        String beginTime = exportExcel.getBeginTime();
        String endTime = exportExcel.getEndTime();

        String[] ids = fields.split(",");
        String area = null;
        if (!Common.ADMIN.equals(loginName)) {
            area = corpDao.getDistinct(loginName);
        }
        if (NumberEnum.ONE.getNum().equals(type)) {
            //判断参数excelRecordId是否为空，如果为空新增导出数据记录，如果不为空修改记录
            commonOperation(isCX, loginName, fields, NumberEnum.ONE.getNum(), excelName, excelRecordId, Common.ZERO);
            //导出企业信息数据 1
            return getCorpExcelData(ids, district, qyName, page, area, registerAddress, street, beginTime, endTime);
        } else if (NumberEnum.TWENTY_NINE.getNum().equals(type)) {
            //判断参数excelRecordId是否为空，如果为空新增导出数据记录，如果不为空修改记录
            commonOperation(isCX, loginName, fields, NumberEnum.TWENTY_NINE.getNum(), excelName, excelRecordId, Common.ZERO);
            //导出企业人员数据 29
            return getCorpPersonExcelData(ids, district, qyName, page, area, insurance, certificate, duties, street, beginTime, endTime);
        } else if (NumberEnum.FORTY_THREE.getNum().equals(type)) {
            //判断参数excelRecordId是否为空，如果为空新增导出数据记录，如果不为空修改记录
            commonOperation(isCX, loginName, fields, NumberEnum.FORTY_THREE.getNum(), excelName, excelRecordId, Common.ZERO);
            //企业年度综合评级数据 43
            return getCorpRecordData(ids, qyName, area, year, dj, page, street, beginTime, endTime, district);
        } else if (NumberEnum.FORTY_EIGHT.getNum().equals(type)) {
            //判断参数excelRecordId是否为空，如果为空新增导出数据记录，如果不为空修改记录
            commonOperation(isCX, loginName, fields, NumberEnum.FORTY_EIGHT.getNum(), excelName, excelRecordId, Common.ZERO);
            //项目信息数据 48
            return getProjectData(ids, area, qyName, projectName, district, page, street, beginTime, endTime);
        } else if (NumberEnum.EIGHTY_SIX.getNum().equals(type)) {
            //判断参数excelRecordId是否为空，如果为空新增导出数据记录，如果不为空修改记录
            commonOperation(isCX, loginName, fields, NumberEnum.EIGHTY_SIX.getNum(), excelName, excelRecordId, Common.ZERO);
            //项目人员信息数据 86
            return getProjectPersonData(ids, qyName, projectName, area, page, street, beginTime, endTime, district);
        } else if (NumberEnum.ONE_HUNDRED_ONE.getNum().equals(type)) {
            //判断参数excelRecordId是否为空，如果为空新增导出数据记录，如果不为空修改记录
            commonOperation(isCX, loginName, fields, NumberEnum.ONE_HUNDRED_ONE.getNum(), excelName, excelRecordId, Common.ZERO);
            //物业用房信息数据 101
            return getProjectHouseData(ids, area, page, qyName, projectName, street, beginTime, endTime, district);
        } else if (NumberEnum.ONE_HUNDRED_ELEVEN.getNum().equals(type)) {
            //判断参数excelRecordId是否为空，如果为空新增导出数据记录，如果不为空修改记录
            commonOperation(isCX, loginName, fields, NumberEnum.ONE_HUNDRED_ELEVEN.getNum(), excelName, excelRecordId, Common.ZERO);
            //业主委员会信息数据 111
            return getProprietorData(ids, area, page, qyName, projectName, street, beginTime, endTime, district);
        } else if (NumberEnum.ONE_HUNDRED_TWENTY_SEVEN.getNum().equals(type)) {
            //判断参数excelRecordId是否为空，如果为空新增导出数据记录，如果不为空修改记录
            commonOperation(isCX, loginName, fields, NumberEnum.ONE_HUNDRED_TWENTY_SEVEN.getNum(), excelName, excelRecordId, Common.ZERO);
            //项目经营情况数据 127
            return getProjectProfitData(ids, area, page, qyName, projectName, street, beginTime, endTime, district);
        } else if (NumberEnum.ONE_HUNDRED_SIXTY_NINE.getNum().equals(type)) {
            //判断参数excelRecordId是否为空，如果为空新增导出数据记录，如果不为空修改记录
            commonOperation(isCX, loginName, fields, NumberEnum.ONE_HUNDRED_SIXTY_NINE.getNum(), excelName, excelRecordId, Common.ZERO);
            //优良负面信息数据 169
            return getScoreDetailData(ids, area, page, qyName, projectName, infoType, street, beginTime, endTime, district);
        } else if (NumberEnum.ONE_HUNDRED_EIGHTY_FOUR.getNum().equals(type)) {
            //判断参数excelRecordId是否为空，如果为空新增导出数据记录，如果不为空修改记录
            commonOperation(isCX, loginName, fields, NumberEnum.ONE_HUNDRED_EIGHTY_FOUR.getNum(), excelName, excelRecordId, Common.ZERO);
            //教育信息数据 184
            return getTrainData(ids, area, page, qyName, department, subject, street, beginTime, endTime, district);
        }
        return null;
    }

    /**
     * 获取等级下拉列表
     *
     * @return 等级列表
     */
    @Override
    public List<String> getDj() {
        List<String> list = excelDao.getDj();
        if (list != null) {
            return list;
        }
        return new ArrayList<>();
    }

    /**
     * 企业信息报表数据
     *
     * @param fields          字段集合
     * @param district        所在区
     * @param qyName          企业名
     * @param page            页码
     * @param area            管理区域
     * @param registerAddress 注册地
     * @return 结果集
     */
    private ManagerPageResult getCorpExcelData(String[] fields, Integer district, String qyName, Page page, String area, String registerAddress, String street, String beginTime, String endTime) {
        ManagerPageResult mpr = new ManagerPageResult();
        JsonResult jr = new JsonResult();
        //导出数据
        int count = excelDao.countCorp(qyName, district, area, registerAddress, street, beginTime, endTime);
        if (count == NumberEnum.ZERO.getNum()) {
            commonResult(mpr, jr);
            return mpr;
        }
        List<Map<String, Object>> list = excelDao.listCorps(qyName, district, fields, page, area, registerAddress, street, beginTime, endTime);
        jr.setDs(list);
        mpr.setCount(count);
        mpr.setJson(jr);
        return mpr;
    }

    /**
     * 导出企业人员信息数据
     *
     * @param fields      字段集合
     * @param district    所在区
     * @param qyName      企业名
     * @param page        页码
     * @param area        管理区域
     * @param insurance   是否缴纳五险一金
     * @param certificate 是否是中级以上职称
     * @param duties      职务
     * @return 结果集
     */
    private ManagerPageResult getCorpPersonExcelData(String[] fields, Integer district, String qyName, Page page, String area, String insurance, String certificate, String duties, String street, String beginTime, String endTime) {
        ManagerPageResult mpr = new ManagerPageResult();
        JsonResult jr = new JsonResult();
        //导出数据
        int count = excelDao.countCorpPerson(district, qyName, insurance, certificate, duties, area, street, beginTime, endTime);
        if (count <= NumberEnum.ZERO.getNum()) {
            commonResult(mpr, jr);
            return mpr;
        }
        List<Map<String, Object>> list = excelDao.listCorpPersons(fields, district, qyName, page, insurance, certificate, duties, area, street, beginTime, endTime);
        jr.setDs(list);
        mpr.setCount(count);
        mpr.setJson(jr);
        return mpr;
    }

    /**
     * 企业年度综合评级数据
     *
     * @param fields 字段集合
     * @param qyName 企业名
     * @param area   管理区域
     * @param year   年度
     * @param dj     等级
     * @param page   页码
     * @return 结果集
     */
    private ManagerPageResult getCorpRecordData(String[] fields, String qyName, String area, String year, String dj, Page page, String street, String beginTime, String endTime, Integer district) {
        ManagerPageResult mpr = new ManagerPageResult();
        JsonResult jr = new JsonResult();
        //导出数据
        int count = excelDao.countCorpRecord(qyName, area, dj, year, street, beginTime, endTime, district);
        if (count <= NumberEnum.ZERO.getNum()) {
            commonResult(mpr, jr);
            return mpr;
        }
        List<Map<String, Object>> list = excelDao.listCorpRecords(fields, qyName, page, area, dj, year, street, beginTime, endTime, district);
        jr.setDs(list);
        mpr.setJson(jr);
        mpr.setCount(count);
        return mpr;
    }

    /**
     * 项目信息数据
     *
     * @param fields   字段集合
     * @param area     所管理区域
     * @param qyName   企业名
     * @param proName  项目名
     * @param district 地区
     * @param page     页码
     * @return 结果集
     */
    private ManagerPageResult getProjectData(String[] fields, String area, String qyName, String proName, Integer district, Page page, String street, String beginTime, String endTime) {
        ManagerPageResult mpr = new ManagerPageResult();
        JsonResult jr = new JsonResult();
        //导出数据
        int count = excelDao.countProject(qyName, area, proName, district, street, beginTime, endTime);
        if (count <= NumberEnum.ZERO.getNum()) {
            commonResult(mpr, jr);
            return mpr;
        }
        List<Map<String, Object>> list = excelDao.listProjects(fields, qyName, area, page, proName, district, street, beginTime, endTime);
        //getName(list, MapUtil.propertyMap, "property_type");
        jr.setDs(list);
        mpr.setJson(jr);
        mpr.setCount(count);
        return mpr;
    }

    /**
     * 项目人员信息数据
     *
     * @param fields  字段集合
     * @param qyName  企业名
     * @param proName 项目名
     * @param area    所管理区域
     * @param page    页码
     * @return 结果集
     */
    private ManagerPageResult getProjectPersonData(String[] fields, String qyName, String proName, String area, Page page, String street, String beginTime, String endTime, Integer district) {
        ManagerPageResult mpr = new ManagerPageResult();
        JsonResult jr = new JsonResult();
        //导出数据
        int count = excelDao.countProjectPerson(qyName, proName, area, district, street, beginTime, endTime);
        if (count <= NumberEnum.ZERO.getNum()) {
            commonResult(mpr, jr);
            return mpr;
        }
        List<Map<String, Object>> list = excelDao.listProjectPersons(fields, qyName, proName, area, page, district, street, beginTime, endTime);
        jr.setDs(list);
        mpr.setCount(count);
        mpr.setJson(jr);
        return mpr;
    }

    /**
     * 项目物业用房信息数据
     *
     * @param fields  字段集合
     * @param qyName  企业名
     * @param proName 项目名
     * @param area    所管理区域
     * @param page    页码
     * @return 结果集
     */
    private ManagerPageResult getProjectHouseData(String[] fields, String area, Page page, String qyName, String proName, String street, String beginTime, String endTime, Integer district) {
        ManagerPageResult mpr = new ManagerPageResult();
        JsonResult jr = new JsonResult();
        //导出数据
        int count = excelDao.countProjectHouse(qyName, proName, area, street, beginTime, endTime, district);
        if (count <= NumberEnum.ZERO.getNum()) {
            commonResult(mpr, jr);
            return mpr;
        }
        List<Map<String, Object>> list = excelDao.listProjectHouses(fields, qyName, proName, area, page, street, beginTime, endTime, district);
        getName(list, MapUtil.roomMap, "room_state");

        jr.setDs(list);
        mpr.setJson(jr);
        mpr.setCount(count);
        return mpr;
    }

    /**
     * 根据传入的代码获取对应的中文意思
     *
     * @param list  数据集合
     * @param beMap map集合
     * @param code  代码类型
     */
    private void getName(List<Map<String, Object>> list, Map<String, String> beMap, String code) {
        for (Map map : list) {
            StringBuffer buffer = new StringBuffer(10);
            String state = (String) map.get(code);
            if (StringUtils.isNotBlank(state)) {
                String[] split = state.split(",");
                for (int i = 0; i < split.length; i++) {
                    String name = beMap.get(split[i]);
                    buffer.append(name).append(",");
                }
                String name = buffer.deleteCharAt(buffer.length() - 1).toString();
                map.put(code, name);
            }

        }
    }

    /**
     * 业主委员会信息数据
     *
     * @param fields  字段集合
     * @param qyName  企业名
     * @param proName 项目名
     * @param area    所管理区域
     * @param page    页码
     * @return 结果集
     */
    private ManagerPageResult getProprietorData(String[] fields, String area, Page page, String qyName, String proName, String street, String beginTime, String endTime, Integer district) {
        ManagerPageResult mpr = new ManagerPageResult();
        JsonResult jr = new JsonResult();
        //导出数据
        int count = excelDao.countProprietor(qyName, proName, area, street, beginTime, endTime, district);
        if (count <= NumberEnum.ZERO.getNum()) {
            commonResult(mpr, jr);
            return mpr;
        }
        List<Map<String, Object>> list = excelDao.listProprietors(fields, qyName, proName, area, page, street, beginTime, endTime, district);
        jr.setDs(list);
        mpr.setCount(count);
        mpr.setJson(jr);
        return mpr;
    }

    /**
     * 项目经营情况信息数据
     *
     * @param fields  字段集合
     * @param qyName  企业名
     * @param proName 项目名
     * @param area    所管理区域
     * @param page    页码
     * @return 结果集
     */
    private ManagerPageResult getProjectProfitData(String[] fields, String area, Page page, String qyName, String proName, String street, String beginTime, String endTime, Integer district) {
        ManagerPageResult mpr = new ManagerPageResult();
        JsonResult jr = new JsonResult();
        //导出数据
        int count = excelDao.countProjectProfit(qyName, proName, area, street, beginTime, endTime, district);
        if (count <= NumberEnum.ZERO.getNum()) {
            commonResult(mpr, jr);
            return mpr;
        }
        List<Map<String, Object>> list = excelDao.listProjectProfits(fields, qyName, proName, area, page, street, beginTime, endTime, district);
        jr.setDs(list);
        mpr.setJson(jr);
        mpr.setCount(count);
        return mpr;
    }

    /**
     * 优良负面信息数据
     *
     * @param fields  字段集合
     * @param qyName  企业名
     * @param proName 项目名
     * @param area    所管理区域
     * @param page    页码
     * @return 结果集
     */
    private ManagerPageResult getScoreDetailData(String[] fields, String area, Page page, String qyName, String proName, Integer infoType, String street, String beginTime, String endTime, Integer district) {
        ManagerPageResult mpr = new ManagerPageResult();
        JsonResult jr = new JsonResult();
        //导出数据
        int count = excelDao.countScoreDetail(qyName, proName, area, infoType, street, beginTime, endTime, district);
        if (count <= NumberEnum.ZERO.getNum()) {
            commonResult(mpr, jr);
            return mpr;
        }
        List<Map<String, Object>> list = excelDao.listScoreDetails(fields, qyName, proName, area, page, infoType, street, beginTime, endTime, district);
        jr.setDs(list);
        mpr.setCount(count);
        mpr.setJson(jr);
        return mpr;
    }

    /**
     * 获取企业教育情况数据
     *
     * @param fields     字段集合
     * @param area       地区
     * @param page       页码
     * @param qyName     企业名
     * @param department 培训部门
     * @param subject    培训科目
     * @return 结果集
     */
    private ManagerPageResult getTrainData(String[] fields, String area, Page page, String qyName, String department, String subject, String street, String beginTime, String endTime, Integer district) {
        ManagerPageResult mpr = new ManagerPageResult();
        JsonResult jr = new JsonResult();
        //导出数据
        int count = excelDao.countTrain(qyName, area, department, subject, street, beginTime, endTime, district);
        if (count <= NumberEnum.ZERO.getNum()) {
            commonResult(mpr, jr);
            return mpr;
        }
        List<Map<String, Object>> list = excelDao.listTrains(fields, qyName, area, page, department, subject, street, beginTime, endTime, district);
        jr.setDs(list);
        mpr.setJson(jr);
        mpr.setCount(count);
        return mpr;
    }

    /**
     * 判断是否是查询接口
     *
     * @param isCX          是否是查询接口
     * @param loginName     登录名
     * @param excelStr      字段集合字符串
     * @param type          导出报表类型
     * @param excelName     excel名
     * @param excelRecordId 报表id
     */
    public void commonOperation(Integer isCX, String loginName, String excelStr, Integer type, String excelName, Integer excelRecordId, String excelType) {
        //判断是否是查询接口，如果不是插入导出报表记录
        if (isCX == null) {
            commonExcelRecord(loginName, excelStr, type, excelName, excelRecordId, excelType);
        }
    }

    /**
     * 操作导出excel记录
     *
     * @param loginName     登录名
     * @param excelStr      字段集合字符串
     * @param type          导出报表类型
     * @param excelName     excel名
     * @param excelRecordId 报表id
     */
    private void commonExcelRecord(String loginName, String excelStr, Integer type, String excelName, Integer excelRecordId, String excelType) {
        ExcelExportRecordVO excelRecord = new ExcelExportRecordVO();
        excelRecord.setType(type);
        excelRecord.setExcelStr(excelStr);
        excelRecord.setExcelName(excelName);
        excelRecord.setAdder(loginName);
        excelRecord.setExcelType(excelType);
        //保存字段对象
        //将字段字符串拆分
        String[] names = excelStr.split(",");
        //通过字段名查询数据库保存在list中
        List<MenuDTO> excelObjs = new ArrayList<>();
        //遍历字段数组查询数据库找到对应的menu对象
        for (String name : names) {
            MenuDTO menuDTO = excelDao.getMenuByName(name, type);
            excelObjs.add(menuDTO);
        }
        //将list装换成json字符串
        JSONArray array = JSONArray.parseArray(JSON.toJSONString(excelObjs));
        String excelObj = JSON.toJSONString(array);
        //将字符串存到对象中，新增更改时保存到数据库中
        excelRecord.setExcelObj(excelObj);
        if (excelRecordId != null) {
            //如果excelRecordId不为null，修改此条数据
            excelRecord.setId(excelRecordId);
            //修改记录
            excelDao.updateExcelRecord(excelRecord);
        } else {
            //如果excelRecordId为null
            // 新增数据
            excelDao.insertExcelRecord(excelRecord);
        }
    }

    private void commonResult(ManagerPageResult mpr, JsonResult jr) {
        mpr.setCount(NumberEnum.ZERO.getNum());
        jr.setDs(new ArrayList());
        mpr.setJson(jr);
    }

}
